import React, { useState, useEffect } from 'react';
import { Select, Button, message } from 'antd';
import { DeleteOutlined } from '@ant-design/icons';
import styled from 'styled-components';
import { getVariableDataType, isDataTypeEqual, isDataTypeMatch } from '../../utils/dataType';
import FilterValue from '../filter/FilterValue';
import DataTypeDisplay from '../common/DataTypeDisplay';
import VariableSelect from '../common/VariableSelect';

const valueType = {
  CONSTANT: 'CONSTANT',
  VARIABLE: 'VARIABLE',
  INPUT_PARAM: 'INPUT_PARAM',
};

const assignTypeList = [
  { value: valueType.CONSTANT, label: '常量' },
  { value: valueType.VARIABLE, label: '变量' },
];

const columns = [
  { name: '参数名称', prop: 'source' },
  { name: '数据类型', prop: 'sourceDataType' },
  { name: '赋值方式', prop: 'targetType' },
  { name: '赋值', prop: 'target' },
];

const RuleSetting = styled.div`
  width: 100%;
`;

const RuleSettingHead = styled.div`
  background-color: #002f5c;  
  padding: 0 1px;
  color: #9ccdff;
`;

const RuleSettingBody = styled.div`
  /* border-left: 1px solid #f2f2f2;
  border-right: 1px solid #f2f2f2; */
`;

const RuleSettingTr = styled.div`
  display: flex;
  /* border-bottom: 1px solid #f2f2f2; */
  height: 36px;
`;

const RuleSettingTd = styled.div`
  flex: 1;
  min-width: 0;
  padding: 0 6px;
  display: flex;
  align-items: center;

  &.required {
    color: red;
    width: 10px;
  }

  &.delete-td {
    width: 40px;
    flex: none;
    justify-content: center;
  }

  &.delete-td {
    width: 20px;
    margin-right: 10px;
    & > .anticon {
      cursor: pointer;
      color: #999;
    }
  }
`;

const RuleSettingFoot = styled.div`
  text-align: center;
  padding: 6px 0;
`;

const InputRuleSetting = ({
  value,
  onChange,
  showRequired = false,
  showTargetType = true,
  addText,
  sourceList = [],
  targetList = [],
  requiredKeys = [],
}) => {
  const [rules, setRules] = useState([...(value || [])]);

  useEffect(() => {
    if (value !== rules) {
      setRules([...value]);
    }
  }, [value]);

  const addRule = () => {
    const newRules = [
      ...rules,
      {
        source: '',
        sourceDataType: null,
        sourceType: valueType.VARIABLE,
        target: '',
        targetDataType: null,
        targetType: valueType.INPUT_PARAM,
        required: false,
      },
    ];
    setRules(newRules);
    onChange?.(newRules);
  };

  const removeRule = (rowIndex) => {
    const newRules = [...rules];
    newRules.splice(rowIndex, 1);
    setRules(newRules);
    onChange?.(newRules);
  };

  const onSourceTypeChange = (rowIndex) => {
    const newRules = [...rules];
    newRules[rowIndex].source = '';
    newRules[rowIndex].sourceDataType = null;
    setRules(newRules);
    onChange?.(newRules);
  };

  const onSourceVarChange = (rowIndex) => {
    const newRules = [...rules];
    const target = newRules[rowIndex].target;
    const targetEnv = sourceList.find(item => item.paramKey === target);

    const source = newRules[rowIndex].source;
    let sourceEnv = getVariableDataType(source, targetList);
    if (!isDataTypeEqual(targetEnv.dataType, sourceEnv.dataType)) {
      message.error('所选变量的数据类型与目标变量数据类型不匹配');
      newRules[rowIndex].source = '';
      setRules(newRules);
      onChange?.(newRules);
      return;
    }
    newRules[rowIndex].sourceDataType = sourceEnv.dataType;
    setRules(newRules);
    onChange?.(newRules);
  };

  const getAvailableTarget = (target) => {
    return sourceList.filter(item => {
      if (item.paramKey === target) {
        return item;
      }
      return !rules.map(item => item.target).includes(item.paramKey);
    });
  };

  const getAvailableSource = (target, targetDataType) => {
    return targetList.filter(item => {
      if (item.envKey === target) {
        return false;
      }
      return isDataTypeMatch(item.dataType, targetDataType);
    });
  };

  const onTargetChange = (rowIndex, value) => {
    const newRules = [...rules];
    const target = value;
    const param = sourceList.find(item => item.paramKey === target);
    newRules[rowIndex].source = '';
    newRules[rowIndex].targetDataType = param.dataType;
    newRules[rowIndex].targetType = param.targetType;
    if (requiredKeys.includes(target)) {
      newRules[rowIndex].required = true;
    }
    setRules(newRules);
    onChange?.(newRules);
  };

  return (
    <RuleSetting>
      <RuleSettingHead>
        <RuleSettingTr>
          {columns.map(column => (
            column.prop === 'targetType' ? (
              showTargetType && (
                <RuleSettingTd key={column.prop}>{column.name}</RuleSettingTd>
              )
            ) : (
              <RuleSettingTd key={column.prop}>{column.name}</RuleSettingTd>
            )
          ))}
          <RuleSettingTd className="delete-td" />
        </RuleSettingTr>
      </RuleSettingHead>
      <RuleSettingBody>
        {rules.map((rule, rowIndex) => (
          <RuleSettingTr key={rowIndex}>
            {columns.map(column => {
              if (column.prop === 'source') {
                return (
                  <RuleSettingTd key={column.prop}>
                    <div className="required">
                      {requiredKeys.includes(rule.target) && <span>*</span>}
                    </div>
                    <Select
                      value={rule.target}
                      disabled={requiredKeys.includes(rule.target)}
                      size="small"
                      onChange={(value) => onTargetChange(rowIndex, value)}
                      style={{ width: '100%' }}
                    >
                      {getAvailableTarget(rule.target).map(item => (
                        <Select.Option key={item.paramKey} value={item.paramKey}>
                          {item.paramName}
                        </Select.Option>
                      ))}
                    </Select>
                  </RuleSettingTd>
                );
              }
              if (column.prop === 'sourceDataType') {
                return (
                  <RuleSettingTd key={column.prop}>
                    <DataTypeDisplay dataType={rule.targetDataType} />
                  </RuleSettingTd>
                );
              }
              if (column.prop === 'targetType' && showTargetType) {
                return (
                  <RuleSettingTd key={column.prop}>
                    <Select
                      value={rule.sourceType}
                      size="small"
                      onChange={() => onSourceTypeChange(rowIndex)}
                      style={{ width: '100%' }}
                    >
                      {assignTypeList.map(item => (
                        <Select.Option key={item.value} value={item.value}>
                          {item.label}
                        </Select.Option>
                      ))}
                    </Select>
                  </RuleSettingTd>
                );
              }
              if (column.prop === 'target') {
                return (
                  <RuleSettingTd key={column.prop}>
                    {rule.sourceType === valueType.CONSTANT ? (
                      <FilterValue
                        value={rule.source}
                        onChange={(value) => {
                          const newRules = [...rules];
                          newRules[rowIndex].source = value;
                          setRules(newRules);
                          onChange?.(newRules);
                        }}
                        dataType={rule.targetDataType}
                        size="small"
                        showNumberControls={false}
                      />
                    ) : (
                      <VariableSelect
                        value={rule.source}
                        onChange={(value) => {
                          const newRules = [...rules];
                          newRules[rowIndex].source = value;
                          setRules(newRules);
                          onSourceVarChange(rowIndex);
                        }}
                        size="small"
                        options={getAvailableSource(rule.target, rule.targetDataType)}
                        filterDataType={rule.targetDataType}
                      />
                    )}
                  </RuleSettingTd>
                );
              }
              return null;
            })}
            <RuleSettingTd className="delete-td">
              {!requiredKeys.includes(rule.target) && (
                <DeleteOutlined onClick={() => removeRule(rowIndex)} />
              )}
            </RuleSettingTd>
          </RuleSettingTr>
        ))}
      </RuleSettingBody>
      <RuleSettingFoot>
        <Button size="small" type="primary" onClick={addRule}>
          {addText || '新增入参'}
        </Button>
      </RuleSettingFoot>
    </RuleSetting>
  );
};

export default InputRuleSetting; 